package cn.yunbamboos.db.core;

import cn.hutool.core.util.ArrayUtil;
import cn.yunbamboos.db.IDB;
import cn.yunbamboos.db.ReadInitDataSQL;
import cn.yunbamboos.db.metadata.TableMetadata;
import com.zaxxer.hikari.HikariDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

public abstract class BaseDB implements IDB {

    private static final Logger logger = LoggerFactory.getLogger(BaseDB.class);

    protected HikariDataSource dataSource;

    @Override
    public void checkDBDir() {

    }

    @Override
    public void checkPid() {

    }

    @Override
    public void connect() {

    }

    public boolean executeExistTableSql(String sql) {
        try {
            Connection conn = dataSource.getConnection();
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(sql);
            boolean result = rs.next();
            rs.close();
            stmt.close();
            conn.close();
            return result;
        } catch (Exception e) {
            logger.error("error", e);
        }
        return false;
    }

    public void executeCreateTableSql(String sql) {
        try {
            Connection conn = dataSource.getConnection();
            Statement stmt = conn.createStatement();
            stmt.execute(sql);
            stmt.close();
            conn.close();
        } catch (Exception e) {
            logger.error("error", e);
        }
    }

    public void executeUpdate(String sql) {
        try {
            Connection conn = dataSource.getConnection();
            conn.setAutoCommit(false);
            Statement statement = conn.createStatement();
            statement.executeUpdate(sql);
            conn.commit();
            statement.close();
            conn.close();
        } catch (Exception e) {
            logger.error("error", e);
        }
    }

    @Override
    public boolean existDB() {
        // MySQL SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'bst-algo-service';
        return false;
    }

    @Override
    public void createDB() {

    }

    @Override
    public boolean existTable(TableMetadata tableMetadata) {
        // MySQL SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'IVAS-SERVICE' AND TABLE_NAME = 'ALARM'
        // H2 SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'PUBLIC' AND TABLE_NAME = 'ALARM'
        // executeQuery("SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'PUBLIC' AND TABLE_NAME = 'ALARM'");
        return false;
    }

    @Override
    public void createTable(TableMetadata tableMetadata) {

    }

    @Override
    public void addColumn() {

    }

    @Override
    public void deleteColumn() {

    }

    /**
     * 检查进程是否存在
     */
    public boolean checkProcess(String name) {
        boolean isRunning = false;
        try {
            Process process = Runtime.getRuntime().exec(new String[]{"ps", "aux"});
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.contains(name)) {
                    isRunning = true;
                    logger.info("{}", line);
                    break;
                }
            }
            reader.close();
        } catch (IOException e) {
            logger.error("check {} running error", name, e);
        }
        return isRunning;
    }

    /**
     * 启动进程
     */
    public void startProcess(String[] cmd) {
        try {
            logger.error("start process cmd: {}", ArrayUtil.join(cmd, " "));
            Process process = Runtime.getRuntime().exec(cmd);
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                logger.info("{}", line);
            }
            reader.close();
        } catch (IOException e) {
            logger.error("start process error cmd: {}", ArrayUtil.join(cmd, " "), e);
        }
    }

    public void unTar(File dir) {
        try {
            Process process = Runtime.getRuntime().exec(new String[]{"tar", "xvf", "/home/app/data.tar"}, null, dir);
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                logger.info("{}", line);
            }
            reader.close();
        } catch (IOException e) {
            logger.error("un tar error", e);
        }
    }

    public void initDataSQL(ReadInitDataSQL read) {

    }

    public void closeDB() {
        if (dataSource != null) {
            dataSource.close();
        }
    }
}
